/*
 * @Author: wangjq4214
 * @Date: 2022-05-23 10:18:38
 * @LastEditTime: 2022-06-05 16:59:50
 * @LastEditors: wangjq4214
 */
package main

import (
	"context"
	"io/ioutil"
	"log"
	"time"

	pb "gitee.com/wangjq4214/schedule/proto/follower"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"gopkg.in/yaml.v2"
)

type Task struct {
	CPU     int    `yaml:"cpu"`
	Storage int    `yaml:"storage"`
	Time    int64  `yaml:"time"`
	Need    bool   `yaml:"need"`
	DataID  int    `yaml:"data-id"`
	DataIP  string `yaml:"data-ip"`
}

type TaskCommit struct {
	client pb.FollowerServeClient
}

func NewTaskCommit(addr string) (*TaskCommit, error) {
	conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("did not connect: %v", err)
		return nil, err
	}

	return &TaskCommit{
		client: pb.NewFollowerServeClient(conn),
	}, nil
}

func (t *TaskCommit) parse_yml(path string) ([]*Task, error) {
	task := make([]*Task, 0)
	res, err := ioutil.ReadFile(path)
	if err != nil {
		log.Fatalf("Read tasks fail, %v", err.Error())
		return nil, err
	}
	err = yaml.Unmarshal(res, &task)
	if err != nil {
		log.Fatalf("Read tasks fail, %v", err.Error())
		return nil, err
	}

	return task, nil
}

func (t *TaskCommit) commit(task *pb.NewTaskReq) error {
	// Contact the server and print out its response.
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	res, err := t.client.NewTask(ctx, task)
	if err != nil {
		log.Printf("could not send: %v", err)
		return err
	}
	log.Printf("Msg: %s", res.GetStatus().GetMsg())
	return nil
}

func (t *TaskCommit) CommitByFile(path string) error {
	task, err := t.parse_yml(path)
	if err != nil {
		return err
	}

	log.Printf("Get %v tasks.\n", len(task))

	tmp := new(pb.NewTaskReq)
	for _, v := range task {
		tmp.Item = append(tmp.Item, &pb.NewTaskItem{
			CPU:     int32(v.CPU),
			Storage: int32(v.Storage),
			Time:    v.Time,
			Need:    v.Need,
			Position: &pb.DataPosition{
				ID: int32(v.DataID),
				IP: v.DataIP,
			},
		})
	}

	err = t.commit(tmp)
	if err != nil {
		return err
	}

	return nil
}

func (t *TaskCommit) CommitByCmd(cpu int, storage int, time int, need bool, dataID int, dataIP string) error {
	tmp := new(pb.NewTaskReq)
	tmp.Item = append(tmp.Item, &pb.NewTaskItem{
		CPU:     int32(cpu),
		Storage: int32(storage),
		Time:    int64(time),
		Need:    need,
		Position: &pb.DataPosition{
			ID: int32(dataID),
			IP: dataIP,
		},
	})

	err := t.commit(tmp)
	if err != nil {
		return err
	}

	return nil
}
